April 1996

Automating common ftp tasks

By Marco C. Mason

Suppose that you manage a large network where multiple machines need to have a local copy of some set of files, and you're frequently updating these same files. You start ftp and transfer the files like this (what you type is in italics):

$ ftp widget1.cobb.zd.com

Connected to widget1.

220 widget1 FTP server (UNIX(r) System V Release 4.0) ready.

Name (Widget1:marco): anonymous

331 Guest login ok, send ident as password.

Password:

ftp> cd /pub/data

250 CWD command successful.

ftp> put daily.summary

200 PORT command successful.

150 ASCII data connection for

daily.summary (140.244.96.202,32817)

226 Transfer complete.

local: daily.summary remote: daily.summary

21468 bytes sent in 11.32 seconds (1.9 Kbytes/s)

ftp>

Ugh! You've sent only one file, and you've barely gotten started. If you need to send a few files in different subdirectories to a dozen machines, you'll be baby-sitting ftp for quite a while. Wouldn't it be better if a command could do all the transfers for you?

In this article, we'll show you how to create macros to make large file transfer jobs simpler using ftp. We'll also show you how to make ftp automatically log you in when you specify the computer to which you want to connect.

Creating macros

The first thing we can do to make ftp simpler to use is to create macros for common tasks. You can create your own commands in ftp by building them out of other ftp commands. These new commands are called macros. You create your commands with the macdef command. To use the macdef command, all you need to do is type macdef and follow it with the name of your new macro. Then, type each command you want your new macro to perform. When you're finished, enter a blank line to tell ftp that your macro is complete.

Figure A shows an example macro, named transfer, that will copy our daily summary files to a remote machine. Please note that this macro assumes that we're already connected to the machine.

Figure A

macdef transfer

cd /pub/data

put daily.summary

put graphs/daily.orders

put graphs /daily.inquiries

put graphs /daily.cancels

cd /pub/spreadsheets

put daily.worksheet.wks

<blank line>

Executing macros

Now that we have our macro, transferring a set of files from our machine to a remote machine is simpler. Once we're connected, all we have to do is tell ftp to execute the new macro. You do so by entering $macroname at an ftp prompt, like this:

ftp> $transfer

Advanced macro operations

Even though transferring all the files to a single remote computer is simple, we still must connect to each machine that we need to update and then execute our macro command. Fortunately, there's a better way. You can write a macro that accepts arguments. In other words, you can write a macro so that when you execute it like this

ftp> $send_files widget1 widget2 arthur

your macro has the ability to read the arguments widget1, widget2, and arthur. To do so, when you write your macro, use the character sequence $1 to refer to the first argument, $2 to refer to the second, and so on. Therefore, we could write the send_files macro to send our files to the machines widget1, widget2, and arthur, as shown in Figure B.

Please note that each argument is separated by spaces, unless you use quotes. If you use quotes, you may embed spaces in your arguments. Thus $transfer "arg 1" "arg 2" has only two arguments.

Figure B

macdef send_files

open $1

$transfer

close

open $2

$transfer

close

open $3

$transfer

close

<blank line>

Figure C

macdef send_files

open $i

$transfer

close

<blank line>

This method is a lot better. Now you can start ftp, issue the send_files macro with the list of machines you want to send the files to, and walk away. No more baby-sitting the computer.

However, this macro could still be improved. First, it's repetitious--whenever you do repetitive tasks on a computer, there's usually a better way. Second, what happens if you want to transfer the daily summaries to more or fewer than three machines?

Both of these problems can be solved by another special character sequence: $i. When you use $i in a macro definition, you're telling ftp to execute the macro once for each argument. The first time ftp executes the macro, $i refers to the first argument. The second time it executes the macro, $i refers to the second argument, and so on, until there are no arguments left. Thus, we can rewrite our send_files macro as shown in Figure C. Using our improved send_files macro, we can transfer our daily summaries to as many machines as we want, simply and easily.

Special notes

Of course, not all is wine and roses. When you're using macros with ftp, you're limited to having only 16 defined at one time. Another limitation is that all your macros combined must have less than 4,096 characters.

In addition, since the $ symbol is used in macro definitions, you can't blithely use it whenever you want one in your macros. In order to put a $ in your macro definitions, you must precede the $ with a \. To put a \ in your macro definitions, you must use \\.

Storing macros for future use

While macros are a very nice feature, why use them if you have to redefine them each time you start the ftp program? Fortunately, the designers had similar thoughts: When you start ftp, it looks in your $HOME directory for a file named .netrc. If it finds this file, it will automatically scan this file for macro definitions and load them into memory. By the time you get to the first prompt, all the macro definitions in the .netrc file are ready to use.

You can put a macro in your .netrc file by entering it just as you would at the ftp prompt. Don't forget to place a blank line after the last line in the macro to end the macro!

The init macro

Do you find yourself executing the same set of commands each time you run ftp? If so, you'll like one of the other benefits of using the .netrc file. It turns out that when ftp loads all the macros in the .netrc file, if it finds one named init, ftp executes it before giving you control.

For example, when you transmit a large file, do you enjoy staring at the screen waiting for the transfer to complete? Neither do we. When we start a file transfer, we open a new terminal window and work on a different project.

Just so we can tell how things are progressing, we always execute the hash command so that ftp will print hash marks (#) as it transfers the file. This way, we can easily look up from our job to see if ftp is still banging away. Similarly, we execute the bell command so that ftp beeps us when the transfer is complete. This allows us to take a break from our other project and start the next file transfer operation.

Rather than execute the bell and hash commands each time we start ftp, we created the init macro, shown in Figure D, in our .netrc file to execute them for us.

Figure D

macdef init

bell

hash

<blank line>

Automatic login

When you examine Figures B and C, you might think we made an error. After all, the open command doesn't automatically log you in, does it? By itself, it doesn't. But if you put the machine definition information into your .netrc file, it can. This is a great feature even if you're not using macros, as it can help you log in to machines without having to type in your user name and password each time.

When you start ftp with a host name on the command line like this

ftp widget1.cobb.zd.com

or if you simply try to open a connection from an ftp prompt, like this

ftp> open widget1.cobb.zd.com

ftp scans its list of machine definitions and, if it finds the specified machine in its list, it will provide whatever information it has. If you specify all the information required, then ftp will automatically log you in without prompting you for the user name and password.

You can create a machine definition by putting the following text in your .netrc file:

machine machine_name

login user_name

password password

All you need to do is replace the italicized text with the required information. You can put the machine, login, and password clauses on a single line if you prefer.

Combining all the concepts we've talked about, we created a .netrc file, shown in Figure E, that contains our macros and machine names so we can perform all our daily summary updates just by starting ftp and typing

$transfer widget1 widget2 arthur

Figure E

machine widget1 login anonymous password marco@widget1

machine widget2 login anonymous password marco@widget1

machine arthur

login marco

password splemliferous

macdef init

bell

hash

macdef transfer

cd /pub/data

put daily.summary

put graphs/daily.orders

put graphs /daily.inquiries

put graphs /daily.cancels

cd /pub/spreadsheets

put daily.worksheet.wks

macdef send_files

open $i

$transfer

close

Temporarily disabling ftp's automatic login feature

Occasionally, you may need to log in to a computer with a different account than the one described in your .netrc file. In this case, you need a way to tell ftp to ignore the machine definition information in your .netrc file but to otherwise run normally.

You can do this by starting ftp with the -n option. This tells ftp to read only the macros from the .netrc file and to ignore the machine definitions. When you use the -n option, you'll have to log in to each machine manually. To start ftp using this switch, just type

ftp -n hostname

Protect yourself!

All the features provided by the .netrc command are great time-savers. However, there's one security problem that you need to be aware of. If you use the automatic login feature with a real account (i.e., not an anonymous login), then anyone who can read your .netrc file can find out your user name and password on that machine.

You can plug this security hole by telling Solaris not to let anyone read the file but you. You can do so by using the command

chmod go-r .netrc

This command tells Solaris to remove the read permission from other accounts inside and outside of your group. Now no one may read your .netrc file but you, the root, and the superuser accounts.

Conclusion

As you can see, ftp has some very powerful features that let you customize its operation. If you take full advantage of the macro facilities and the machine-definition features, you can simplify your daily chores considerably.

Marco C. Mason is a freelance computer consultant and author based in Louisville, Kentucky. He's worked on cattle feeding systems, automated destructive equipment testing, and the largest computer-controlled sound system in the world.


[Return to Index for Inside Solaris - April 1996 Issue]

Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.

Inside Solaris is a publication of The Cobb Group.
1-800-223-8720